package com.yungam.imcs.controller.hand_inspect.analysis;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.yungam.common.bean.hand_inspect.ProcessInspectionHand;
import com.yungam.common.bean.hand_inspect.ProductInspectionHand;
import com.yungam.common.bean.product.ProductInfo;
import com.yungam.common.response.RetDTO;
import com.yungam.common.service.ProcessInspectionHandService;
import com.yungam.common.service.ProductInfoService;
import com.yungam.common.service.ProductInspectionHandService;
import com.yungam.common.utils.DateUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Map;

@Api(tags = "质量检验趋势分析页面接口")
@RestController
@RequestMapping("/inspect_analysis")
public class InspectAnalysisController {

    @Resource
    private DateUtils dateUtils;
    @Resource
    private ProductInfoService productInfoService;
    @Resource
    private ProductInspectionHandService productInspectionHandService;
    @Resource
    private ProcessInspectionHandService processInspectionHandService;

    @ApiOperation("获取良品率统计数据")
    @GetMapping("/cntSum")
    public RetDTO<?> getCntSumData() {
        Map<String, Object> ans = Maps.newHashMap();

        // 昨日良品信息 (不统计 state 为空的数据)
        int lastPercent; // 昨日良品率
        String[] range = dateUtils.getYesterdayRange();
        List<ProductInspectionHand> lastList = productInspectionHandService.list(new QueryWrapper<ProductInspectionHand>()
                .between("create_time", range[0], range[1]).isNotNull("state"));
        int count = (int) lastList.stream().filter(v -> v.getState() == 1).count();
        lastPercent = lastList.size() == 0 ? 0 : (int) Math.ceil((double) count / lastList.size() * 100);

        // 历史良品数据
        int historyPercent; // 历史良品率
        List<ProductInspectionHand> list = productInspectionHandService.list(new QueryWrapper<ProductInspectionHand>().isNotNull("state"));
        int len = list.size(), good = 0;
        Map<String, Integer[]> map = Maps.newHashMap(); // 记录 各产品的<良品, 总数>
        for (ProductInspectionHand pih : list) {
            String productNo = pih.getProductNo();
            Integer[] cur = map.getOrDefault(productNo, new Integer[] {0, 0});
            if (pih.getState() == 1) {
                good++;
                cur[0]++;
            }
            cur[1]++;
            map.put(productNo, cur);
        }
        historyPercent = len == 0 ? 0 : (int) Math.ceil((double) good / len * 100);
        ans.put("percent", Lists.newArrayList(lastPercent, historyPercent)); // 昨日 & 历史 良品率
        ans.put("cnt", new int[] {good, len - good});

        // 整理各产品的良品信息
        List<ProductInfo> products = productInfoService.list();
        Map<String, String> productMap = Maps.newHashMap();
        for (ProductInfo p : products) productMap.put(p.getProductNo(), p.getProductName()); // productNo 对应的 productName

        List<Map<String, Object>> typeList = Lists.newArrayList();
        for (String s : map.keySet()) {
            Map<String, Object> item = Maps.newHashMap();
            item.put("productNo", s);
            item.put("productName", productMap.get(s));
            Integer[] arr = map.get(s);
            item.put("total", arr[1]);
            item.put("good", arr[0]);
            int bad = Math.max((arr[1] - arr[0]), 0);
            item.put("bad", bad);
            typeList.add(item);
        }
        ans.put("products", typeList);
        return RetDTO.data(ans);
    }

    @ApiOperation("获取次品工序占比数据")
    @GetMapping("/badProcessCnt")
    public RetDTO<?> getBadProcessCnt() {
        // 获取所有不合格的工序信息
        List<ProcessInspectionHand> list = processInspectionHandService.list(new QueryWrapper<ProcessInspectionHand>()
                .eq("state", 0));
        int len = list.size();
        if (len == 0) return RetDTO.data(null);

        Map<String, Integer> map = Maps.newHashMap();
        for (ProcessInspectionHand pih : list) {
            int cur = map.getOrDefault(pih.getProcessName(), 0);
            map.put(pih.getProcessName(), cur + 1);
        }

        List<Map<String, Object>> ans = Lists.newArrayList();
        // 计算百分比
        for (String s : map.keySet()) {
            double cnt = map.get(s);
            double percent = Double.parseDouble(String.format("%.1f", cnt / len * 100));
            Map<String, Object> item = Maps.newHashMap();
            item.put("processName", s);
            item.put("percent", percent);
            ans.add(item);
        }
        // 比例从高到低
        ans.sort((x, y) -> (int) ((Double) y.get("percent") - (Double) x.get("percent")));
        return RetDTO.data(ans);
    }

    /* 良品率趋势图数据 */
    /*
    * 周 & 月 & 年的平均良品率
    * */
    @ApiOperation("良品率趋势图数据")
    @GetMapping("/inspection_trend")
    public RetDTO<?> getInspectionTrendData() {
        Map<String, Object> ans = Maps.newHashMap();
        List<List<Double>> list = Lists.newArrayList(); // 返回结果
        LocalDateTime now = LocalDateTime.now(); // 当前时间
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"),
                        sdf2 = new SimpleDateFormat("yyyy-MM");
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd"),
                            df2 = DateTimeFormatter.ofPattern("yyyy-MM");

        String start, end;
        // 计算本周 7 天每天的良品率
        LocalDateTime weekStart = now.minusDays(6);
        start = df.format(weekStart) + " 00:00:00";
        end = df.format(now) + " 23:59:59";
        List<ProductInspectionHand> weekList = productInspectionHandService.list(new QueryWrapper<ProductInspectionHand>()
                .isNotNull("state").between("create_time", start, end));
        Map<String, Integer[]> weekMap = Maps.newHashMap(); // 数组[良品数, 总数]
        for (ProductInspectionHand pih : weekList) {
            String date = sdf.format(pih.getCreateTime());
            Integer[] arr = weekMap.getOrDefault(date, new Integer[]{0, 0});
            arr[1]++;
            if (pih.getState() == 1) arr[0]++;
            weekMap.put(date, arr);
        }
        Map<String, Double> weekPercentMap = Maps.newHashMap();
        for (String s : weekMap.keySet()) {
            double cnt = weekMap.get(s)[1], good = weekMap.get(s)[0];
            double percent = cnt == 0 ? 0 : Double.parseDouble(String.format("%.1f", good / cnt * 100));
            weekPercentMap.put(s, percent);
        }
        List<Double> weekData = Lists.newArrayList();
        for (int i = 0; i < 7; i++) {
            LocalDateTime cur = weekStart.plusDays(i);
            String curDate = df.format(cur);
            double percent = weekPercentMap.getOrDefault(curDate, 0d);
            weekData.add(percent);
        }
        list.add(weekData);

        // 计算月 30 天每天的良品率
        LocalDateTime monthStart = now.minusDays(29);
        start = df.format(monthStart) + " 00:00:00";
        end = df.format(now) + " 23:59:59";
        List<ProductInspectionHand> monthList = productInspectionHandService.list(new QueryWrapper<ProductInspectionHand>()
                .isNotNull("state").between("create_time", start, end));
        Map<String, Integer[]> monthMap = Maps.newHashMap(); // 数组[良品数, 总数]
        for (ProductInspectionHand pih : monthList) {
            String date = sdf.format(pih.getCreateTime());
            Integer[] arr = monthMap.getOrDefault(date, new Integer[]{0, 0});
            arr[1]++;
            if (pih.getState() == 1) arr[0]++;
            monthMap.put(date, arr);
        }
        Map<String, Double> monthPercentMap = Maps.newHashMap();
        for (String s : monthMap.keySet()) {
            double cnt = monthMap.get(s)[1], good = monthMap.get(s)[0];
            double percent = cnt == 0 ? 0 : Double.parseDouble(String.format("%.1f", good / cnt * 100));
            monthPercentMap.put(s, percent);
        }
        List<Double> monthData = Lists.newArrayList();
        for (int i = 0; i < 30; i++) {
            LocalDateTime cur = monthStart.plusDays(i);
            String curDate = df.format(cur);
            double percent = monthPercentMap.getOrDefault(curDate, 0d);
            monthData.add(percent);
        }
        list.add(monthData);

        // 计算年 12 月每月的良品率
        LocalDateTime yearStart = now.minusMonths(11);
        start = df.format(yearStart) + " 00:00:00";
        end = df.format(now) + " 23:59:59";
        List<ProductInspectionHand> yearList = productInspectionHandService.list(new QueryWrapper<ProductInspectionHand>()
                .isNotNull("state").between("create_time", start, end));
        Map<String, Integer[]> yearMap = Maps.newHashMap(); // 数组[良品数, 总数]
        for (ProductInspectionHand pih : yearList) {
            String date = sdf2.format(pih.getCreateTime()); // 按月统计  2021-12 使用 sdf2 转换
            Integer[] arr = yearMap.getOrDefault(date, new Integer[]{0, 0});
            arr[1]++;
            if (pih.getState() == 1) arr[0]++;
            yearMap.put(date, arr);
        }
        Map<String, Double> yearPercentMap = Maps.newHashMap();
        for (String s : yearMap.keySet()) {
            double cnt = yearMap.get(s)[1], good = yearMap.get(s)[0];
            double percent = cnt == 0 ? 0 : Double.parseDouble(String.format("%.1f", good / cnt * 100));
            yearPercentMap.put(s, percent);
        }
        List<Double> yearData = Lists.newArrayList();
        for (int i = 0; i < 12; i++) {
            LocalDateTime cur = yearStart.plusMonths(i);
            String curDate = df2.format(cur);
            double percent = yearPercentMap.getOrDefault(curDate, 0d);
            yearData.add(percent);
        }
        list.add(yearData);
        ans.put("chartData", list);

        // 总良品率
        int historyPercent; // 历史良品率
        List<ProductInspectionHand> historyList = productInspectionHandService.list(new QueryWrapper<ProductInspectionHand>().isNotNull("state"));
        int len = historyList.size(), good = 0;
        Map<String, Integer[]> map = Maps.newHashMap(); // 记录 各产品的<良品, 总数>
        for (ProductInspectionHand pih : historyList) {
            String productNo = pih.getProductNo();
            Integer[] cur = map.getOrDefault(productNo, new Integer[] {0, 0});
            if (pih.getState() == 1) {
                good++;
                cur[0]++;
            }
            cur[1]++;
            map.put(productNo, cur);
        }
        historyPercent = len == 0 ? 0 : (int) Math.ceil((double) good / len * 100);
        ans.put("totalPercent", historyPercent);
        return RetDTO.data(ans);
    }

}
